package com.qqtech.qquan.im.service;

import javax.annotation.Resource;

import org.apache.http.HttpStatus;
import org.glassfish.jersey.client.JerseyWebTarget;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.qqtech.core.frame.dao.BaseDao;
import com.qqtech.core.frame.service.BaseServiceImpl;
import com.qqtech.qquan.im.dao.ImUserDao;
import com.qqtech.qquan.im.enums.HTTPMethod;
import com.qqtech.qquan.im.enums.ImRetrunEnum;
import com.qqtech.qquan.im.enums.ImUserStatusEnum;
import com.qqtech.qquan.im.helper.ImSettings;
import com.qqtech.qquan.im.jersey.Credential;
import com.qqtech.qquan.im.jersey.EndPoints;
import com.qqtech.qquan.im.jersey.JerseyUtils;
import com.qqtech.qquan.im.model.ImUser;
import com.qqtech.qquan.im.model.ImUserVo;

@Service
public class ImUserServiceImpl extends BaseServiceImpl<ImUser>
		implements ImUserService {
	public static final Logger LOGGER = LoggerFactory.getLogger(ImUserServiceImpl.class);
	private static final JsonNodeFactory factory = new JsonNodeFactory(false);
	
	@Resource
	private ImUserDao imUserDao;
	@Resource
    private ImSettings imSettings;
	@Resource
	private Credential credential;

	@Override
	protected BaseDao<ImUser> getBaseDao() {
		return imUserDao;
	}

	@Override
	public Integer addImUser(Integer userId,String imNickName) {
		String imUserId=System.currentTimeMillis()+""+userId;//环信用户ID: 当前时间+用户ID		
		String imPassWord ="qquan^&*"+userId+"^";//环信用户密码："qquan^&*"+用户ID+"^"
		if(imUserDao.getByUserId(userId)!=null){//用户userId已注册，不能重复注册			
			return 0;
		}
		try {
			int retCode = this.addImUserByApi(imUserId, imPassWord, imNickName);
		    if(retCode==ImRetrunEnum.SUCESS.getCode()){
		    	ImUser imUser =new ImUser();
		    	imUser.setUserId(userId);
		    	imUser.setImId(imUserId);
		    	imUser.setImPassWord(imPassWord);
		    	imUser.setImNickName(imNickName);
		    	imUser.setPhone("");
		    	return imUserDao.insert(imUser);
		    }else{
		    	return 0;
		    }
		} catch (Exception e) {
			return 0;
		}
	}
	
	@Override
	public Integer syncImUser2HuanXin(String imUserId,String imPassWord, String imNickName) {		
		ImUserStatusEnum ret = getUserStatusByApi(imUserId);
		if(ret == ImUserStatusEnum.NOTEXIST){
			//如果用没有没有在环信服务上注册，就重新注册一下
			int retCode = this.addImUserByApi(imUserId, imPassWord, imNickName);
		    if(retCode==ImRetrunEnum.SUCESS.getCode()){
		    	return 1;
		    }else{
		    	return 0;
		    }
			
		}
		return 0;
	}

	@Override
	public Integer deleteImUser(Integer userId) {
		ImUser imUser =imUserDao.getByUserId(userId);
		if(imUser!=null){
			String imId = imUser.getImId();
			int deleCount =imUserDao.delete(imUser);
			if(deleCount==1){
				ObjectNode returnObj = this.deleteImUserByApi(imId);
				int statuscode=returnObj.get("statusCode").asInt();
				if(statuscode==HttpStatus.SC_OK){
					return ImRetrunEnum.SUCESS.getCode();
				}else{
					return ImRetrunEnum.FAIL.getCode();//失败
				}
			}else{
				return ImRetrunEnum.FAIL.getCode();//失败
			}
		}else{
			return ImRetrunEnum.FAIL.getCode();//失败
		}
	}
	
	/**
	 * 在环信服务上添中一个用户
	 * @param imUserId
	 * @param imPassWord
	 * @param imNickName
	 * @param phone
	 * @return
	 */
	private Integer addImUserByApi(String imUserId, String imPassWord, String imNickName) {		
		ObjectNode dataNode = factory.objectNode();
		dataNode.put("username", imUserId);
		dataNode.put("password", imPassWord);
		dataNode.put("nickname", imNickName);
		
		ObjectNode objectNode = factory.objectNode();
		objectNode.removeAll();
		// check properties that must be provided
		if (null != dataNode && !dataNode.has("username")) {
			LOGGER.error("Property that named username must be provided .");
			return ImRetrunEnum.FAIL.getCode();
		}
		if (null != dataNode && !dataNode.has("password")) {
			LOGGER.error("Property that named password must be provided .");
			return ImRetrunEnum.FAIL.getCode();
		}
		try {
			String APPKEY = imSettings.getAppKey();
			JerseyWebTarget webTarget = EndPoints.USERS_TARGET.resolveTemplate("org_name",
					APPKEY.split("#")[0]).resolveTemplate("app_name",
					APPKEY.split("#")[1]);
			objectNode = JerseyUtils.sendRequest(webTarget, dataNode, credential, HTTPMethod.METHOD_POST, null);
		    if(objectNode.get("statusCode").asInt()==HttpStatus.SC_UNAUTHORIZED){//401验证失败
		    	credential.getNewToken();//重新获取一个token
		    	objectNode = JerseyUtils.sendRequest(webTarget, dataNode, credential, HTTPMethod.METHOD_POST, null);
		    }
			if (null != objectNode) {
				LOGGER.info("注册IM用户[单个]: " + objectNode.toString());
	        	int statusCode =objectNode.get("statusCode").asInt();//200成功，400用户已存在
			    if(statusCode!=HttpStatus.SC_OK){
			    	return ImRetrunEnum.FAIL.getCode();
			    }else{
			    	return ImRetrunEnum.SUCESS.getCode();
			    }
	        }
		} catch (Exception e) {
			e.printStackTrace();
		}

		return ImRetrunEnum.FAIL.getCode();
	}
	
	/**
	 * 在环信服务上删除一个用户
	 * @param imId
	 * @return
	 */
	private ObjectNode deleteImUserByApi(String imId) {
		ObjectNode objectNode = factory.objectNode();
		try {
			String APPKEY = imSettings.getAppKey();
			JerseyWebTarget webTarget = EndPoints.USERS_TARGET
					.resolveTemplate("org_name", APPKEY.split("#")[0])
					.resolveTemplate("app_name", APPKEY.split("#")[1])
					.path(imId);

			objectNode = JerseyUtils.sendRequest(webTarget, null, credential,HTTPMethod.METHOD_DELETE, null);
			int statusCode = objectNode.get("statusCode").asInt();// 200成功，401验证失败
			if(statusCode==HttpStatus.SC_UNAUTHORIZED){//401验证失败
				credential.getNewToken();//重新获取一个token
		    	objectNode = JerseyUtils.sendRequest(webTarget, null, credential,HTTPMethod.METHOD_DELETE, null);
		    }

		} catch (Exception e) {
			e.printStackTrace();
		}
		return objectNode;
	}

	@Override
	public ImUserVo getByUserId(Integer userId) {
		return imUserDao.getByUserId(userId);
	}

	@Override
	public ImUserVo getByImId(String imId) {
		return imUserDao.getByImId(imId);
	}

	@Override
	public ImUserStatusEnum getImUserStatus(Integer userId) {
		ImUser imUser =imUserDao.getByUserId(userId);
		if(imUser!=null){
			String imId = imUser.getImId();
			return getUserStatusByApi(imId);
		}else{
			return ImUserStatusEnum.NOTEXIST;
		}
	}
	
	private ImUserStatusEnum getUserStatusByApi(String imUserId){
		ObjectNode objectNode = factory.objectNode();
		try {
			String APPKEY = imSettings.getAppKey();
			JerseyWebTarget webTarget = EndPoints.USERS_TARGET
					.resolveTemplate("org_name", APPKEY.split("#")[0])
					.resolveTemplate("app_name", APPKEY.split("#")[1])
					.path(imUserId)
					.path("status");
			objectNode = JerseyUtils.sendRequest(webTarget, null, credential, HTTPMethod.METHOD_GET, null);
			int statusCode = objectNode.get("statusCode").asInt();// 200成功，401验证失败
			if(statusCode==HttpStatus.SC_UNAUTHORIZED){//401验证失败
		    	credential.getNewToken();//重新获取一个token
		    	objectNode = JerseyUtils.sendRequest(webTarget, null, credential, HTTPMethod.METHOD_GET, null);
		    }
			
			if (statusCode == HttpStatus.SC_OK) {// 200
				String userStatus = objectNode.get("data").path(imUserId).asText();
				if ("online".equals(userStatus)) {
					return ImUserStatusEnum.ONLINE;
				} else if ("offline".equals(userStatus)) {
					return ImUserStatusEnum.OFFLINE;
				}
			} else if (statusCode == HttpStatus.SC_NOT_FOUND) {// 404不存在
				return ImUserStatusEnum.NOTEXIST;
			} else {
				return ImUserStatusEnum.ERROR;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return ImUserStatusEnum.ERROR;
	}

	@Override
	public boolean forceImUserOffLine(String userImId) {
		ObjectNode objectNode = factory.objectNode();
		try {
			String APPKEY = imSettings.getAppKey();
			JerseyWebTarget webTarget = EndPoints.USERS_TARGET
					.resolveTemplate("org_name", APPKEY.split("#")[0])
					.resolveTemplate("app_name", APPKEY.split("#")[1])
					.path(userImId)
					.path("disconnect");
			objectNode = JerseyUtils.sendRequest(webTarget, null, credential, HTTPMethod.METHOD_GET, null);
			int statusCode = objectNode.get("statusCode").asInt();// 200成功，401验证失败
			if(statusCode==HttpStatus.SC_UNAUTHORIZED){//401验证失败
		    	credential.getNewToken();//重新获取一个token
		    	objectNode = JerseyUtils.sendRequest(webTarget, null, credential, HTTPMethod.METHOD_GET, null);
		    }
			if (statusCode == HttpStatus.SC_OK) {// 200
				boolean isSuccess = objectNode.get("data").path("result").asBoolean();
				return isSuccess;
			} else {
				return false;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}
	
}